package com.scalar.chiptrack.adaptor.ibm;

import com.scalar.chiptrack.jobs.JobHandler;
import com.scalar.chiptrack.adaptor.AdaptorConstants;
import com.scalar.chiptrack.adaptor.AdaptorUtils;
import com.scalar.chiptrack.adaptor.FabSortLot;
import com.scalar.chiptrack.adaptor.ShippedLot;
import com.scalar.chiptrack.adaptor.utils.ParserResult;
import com.scalar.chiptrack.adaptor.utils.Parser;
import com.scalar.chiptrack.adaptor.utils.ParserFactory;
import com.scalar.chiptrack.adaptor.utils.CSVParserImpl;
import com.scalar.chiptrack.adaptor.dao.FabSortAdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.ShippedLotDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorRunInfo;
import com.scalar.chiptrack.utils.Logger;
import com.scalar.chiptrack.utils.StringUtils;
import com.scalar.chiptrack.db.DBTransaction;
import com.scalar.ScalarException;

import java.util.HashMap;
import java.util.ArrayList;
import java.io.File;

/**
 * Created by IntelliJ IDEA.
 * User: munugoti
 * Date: 20 Nov, 2009
 * Time: 3:37:08 PM
 */
public class IBMDataParser extends JobHandler implements AdaptorConstants
{
    private static Logger m_parserLogger    = null;
    private String m_dataOutputDir          = null;

    private HashMap<String, FabSortLot> m_fabWipDataMap        = new HashMap<String, FabSortLot>();
    private HashMap<String, ShippedLot> m_fabShipDataMap       = new HashMap<String, ShippedLot>();

    public IBMDataParser() throws ScalarException
    {
        try
        {
            m_dataOutputDir = AdaptorUtils.getDataOutputDir( VENDOR_NAME_IBM, WIP_TYPE_FAB );
            AdaptorUtils.makeAllAdaptorDirs( m_dataOutputDir );
            m_parserLogger = AdaptorUtils.getDataParserLogger( m_dataOutputDir,VENDOR_NAME_IBM );
            FabSortAdaptorDAO.setLogger( m_parserLogger );   // All the DAOs and Parser should be logging into same file
            ShippedLotDAO.setLogger( m_parserLogger );
            AdaptorUtils.setLogger( m_parserLogger );
        }
        catch (ScalarException se)
        {
            log("ERROR!! ERROR!! ERROR!! Exception while loading/creating IBM output directory from database, Exception: " + se);
            throw se;
        }
    }
    /**
     *
     * @param args
     * @throws Exception
     */
    public static void main( String args[] ) throws Exception
    {
        try
        {
            new IBMDataParser().execute();
        }
        catch (Exception e)
        {
            throw e;
        }
    }

    //Execute Method
    public void execute() throws Exception
	{
       AdaptorUtils.printHeader( VENDOR_NAME_IBM, CONSTANT_PARSER );

       File doneDestDir = new File( m_dataOutputDir + "/done" );

       File wipDataoutDir = new File( m_dataOutputDir );

       File[] fileList = wipDataoutDir.listFiles();

       if ( ( fileList == null ) || ( fileList.length <= 3 ) )
       {
           log( "No file found in directory: " + wipDataoutDir );
           throw new ScalarException( "No file found in directory: " + wipDataoutDir + "----\n\n" );
       }

       DBTransaction dbTransaction 	= null;
       ArrayList<File> successFileList   	= new ArrayList<File>();
       boolean success             	= false;

       try
       {
           for ( int i = 0; i < fileList.length; i++ )
           {
               if ( fileList[i].isDirectory() )
               {
                   continue;
               }

               if ( fileList[i].getName() != null && fileList[i].getName().trim().startsWith(IBMAdaptor.FILE_NAME_WIP_STATUS) )
               {
               	 	parseDailyWipReport( fileList[i].getAbsolutePath() );

                    successFileList.add( fileList[i] );
               }

               if ( fileList[i].getName() != null && fileList[i].getName().trim().startsWith(IBMAdaptor.FILE_NAME_SHIP_STATUS) )
               {
               	 	parseShipmentReport( fileList[i].getAbsolutePath() );

                    successFileList.add( fileList[i] );
               }
           }
           success= true;
       }
       catch ( Exception e )
       {
           success = false;
           log( "ERROR!! ERROR!! ERROR!! While parsing and storing File " + e );
           e.printStackTrace();
           throw e;
       }

        // to save the FAB lot tables
       try
       {
           if ( m_fabWipDataMap.isEmpty() == false )
           {
               log( " Updating Fab Lot Information" );
               FabSortAdaptorDAO.saveFabLot( null, m_fabWipDataMap.values().iterator(), WIP_TYPE_FAB, VENDOR_NAME_IBM );
           }
           else
           {
               FabSortAdaptorDAO.closeFabSortLot( dbTransaction, WIP_TYPE_FAB, VENDOR_NAME_IBM );
           }
           success = true;
      }
      catch (ScalarException se)
      {
          success = false;
          se.printStackTrace();
          log("ERROR!! ERROR!! ERROR!! Could not update Fab Lot information into database: " + se);
          throw se;
      }

      try
        {
            // Save shipping info -
            if ( m_fabShipDataMap.isEmpty() == false )
            {
                log( "Updating shipment Information" );
                ShippedLotDAO.saveShippedLot( null, m_fabShipDataMap.values().iterator() );
            }
            success = true;
        }
        catch ( Exception e )
        {
            success = false;
            log( "ERROR!! ERROR!! ERROR!! Could not update IBM Shipping information into database: " + e );
            e.printStackTrace();
            throw e;
        }
      // To Close the Drop Out Lots
      AdaptorDAO.closeDropOutLots( VENDOR_NAME_IBM );

      // TO SEND THE NEW LOTS, NEW TRANSIT LOTS, NO PO LOTS, DISCREPANCY LOTS NOTIFICATIONS TO THE USER
      AdaptorDAO.sendAllNotifications( VENDOR_NAME_IBM, true, true, true );

      int adaptor_id = AdaptorRunInfo.getLastRunAdaptorId( IBMAdaptor.ADAPTOR_NAME, CONSTANT_ADAPTOR);

      // Update Adaptor_Run_Info table
      try
      {
            if ( success == true )
            {
                AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, IBMAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id );
                System.out.println( "SUCCESSFULLY UPDATED IN THE DATABASE" );
            }
      }
      catch ( ScalarException se )
      {
            success = false; //As filES DATA SAVED , UPDATEING AS SUCCESS
            AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, IBMAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
            log( "WARNING!! WARNING!! WARNING!! Could not update Adaptor run information, Exception: " + se );
            throw se;
       }
        // Move the successful files to 'done' directory
       if ( success )
       {
           AdaptorUtils.moveFilesToDone( successFileList, doneDestDir );
       }
   }//end of execute method


   	private void parseDailyWipReport( String fileName ) throws Exception
   	{
   		if ( fileName == null ) throw new ScalarException( "Filename argument is null" );

        ParserResult result            = null;
        FabSortLot fabSortLot   = null;
        String lotNumber        = null;
        String partNumber       = null;

        try
        {
            File fabWipFile = new File( fileName );
            if ( fabWipFile.exists() == false )
            {
                throw new ScalarException( fileName + " doesnt exist" );
            }

            log( "\nFound " + fileName );
            log( "\nParsing the file for Fab Wip Report..." );
            System.out.println( "\nFound " + fileName );
            System.out.println( "\nParsing the file for Fab Wip Report..." );

            Parser parser = ParserFactory.getCSVParser( fabWipFile, ',' );

            ((CSVParserImpl)parser).setHeaderRowIdx(0);
            ((CSVParserImpl)parser).setDataStartRowIdx(1);

            result = parser.parse();

            while ( result.next() )
            {
                partNumber = result.getString("Customer part #");
                lotNumber  = result.getString("Primary lot ID");

                if ( partNumber != null && partNumber.trim().length() > 0 && lotNumber != null && lotNumber.trim().length() > 0 )
                {
                     partNumber = partNumber.split("::")[0].trim();

                     fabSortLot = ( FabSortLot ) m_fabWipDataMap.get( partNumber + lotNumber );
                     if ( fabSortLot == null )
                     {
                         fabSortLot = new FabSortLot( VENDOR_NAME_IBM, WIP_TYPE_FAB );
                         m_fabWipDataMap.put( partNumber + lotNumber , fabSortLot );
                     }

                     int quantity = 0;

                     if( fabSortLot.getQtyIn() != null )
                     {
                         try
                         {
                             quantity = Integer.parseInt( fabSortLot.getQtyIn() );
                         }
                         catch ( NumberFormatException ignore )
                         {
                         }
                         quantity += result.getInt("Projected quantity");
                     }
                     else
                     {
                         quantity = result.getInt("Projected quantity");
                     }

                     if ( quantity > 0 )
                     {
                         fabSortLot.setLotId( lotNumber );
                         fabSortLot.setCustProduct( partNumber );
                         fabSortLot.setFabLotNumber( lotNumber );
                         if ( result.getString("Lot Start Date") != null )
                         {
                            fabSortLot.setDateIn( StringUtils.formatDate(result.getString("Lot Start Date"), "MM-dd-yyyy", "MM/dd/yyyy" ) );
                         }    
                         fabSortLot.setQtyIn( quantity +"");
                         fabSortLot.setStage( result.getString("IBM band") );
                         fabSortLot.setStagePosition( result.getString("Gate description") );
                         fabSortLot.setFabLotNumber( lotNumber );
                         /*if ( result.getString("Lot Type") != null )
                         {
                             if ( "PROD".equalsIgnoreCase(result.getString("Lot Type")) )
                             {
                                fabSortLot.setLotCategory( LOT_CATEGORY_TYPE_PROD );
                             }
                             else if ( "ENG".equalsIgnoreCase(result.getString("Lot Type")) )
                             {
                                fabSortLot.setLotCategory( LOT_CATEGORY_TYPE_ENGG );
                             }
                         }*/
                         fabSortLot.setLotCategory( LOT_CATEGORY_TYPE_PROD );
                         fabSortLot.setWsQty( result.getInt("Projected quantity")+"" );
                         fabSortLot.setShip_fcst_date( StringUtils.formatDate(result.getString("Outlook date"), "MM-dd-yyyy", "MM/dd/yyyy" ));
                         fabSortLot.setForcastedDateOut( StringUtils.formatDate(result.getString("Confirmed date"), "MM-dd-yyyy", "MM/dd/yyyy" ) );
                         fabSortLot.setOutLookDate( StringUtils.formatDate(result.getString("Outlook date"), "MM-dd-yyyy", "MM/dd/yyyy" ) );
                         fabSortLot.setPoNumber( result.getString("PO number"));
                         fabSortLot.setFabId( result.getString("Facility") );
                         if ( result.getString("On hold code") != null )
                         {
                            fabSortLot.setLotStatus( LOT_STATUS_HOLD );
                         }
                         else
                         {
                             fabSortLot.setLotStatus( LOT_STATUS_RUNNING );
                         }
                     }
                }

            }
        }
        catch ( Exception ex )
        {   System.out.println("ERROR!!!ERROR!!! While Parsing the IBM Daily wip Sheet");
            ex.printStackTrace();
            throw ex;
        }

    }

    private void parseShipmentReport( String fileName ) throws Exception
    {
        if ( fileName == null ) throw new ScalarException( "Filename argument is null" );

        ParserResult result     = null;
        ShippedLot shippedLot   = null;
        String lotNumber        = null;
        String partNumber       = null;
        String shipDate         = null;
        String nextLocation     = null;

        try
        {
            File detailShipFile = new File( fileName );
            if ( detailShipFile.exists() == false )
            {
                throw new ScalarException( fileName + " doesnt exist" );
            }

            log( "\nFound " + fileName );
            log( "\nParsing the file for Ship Report..." );
            System.out.println( "\nFound " + fileName );
            System.out.println( "\nParsing the file for Ship Report..." );

            Parser parser = ParserFactory.getCSVParser( detailShipFile, ',' );

            ((CSVParserImpl)parser).setHeaderRowIdx(0);
            ((CSVParserImpl)parser).setDataStartRowIdx(1);

            result = parser.parse();
            //System.out.println("result.getHeadings() = " + result.getHeadings());
            while ( result != null && result.next() )
            {
                partNumber = result.getString("Customer part");
                lotNumber = result.getString("Batch");
                
                shipDate   =   StringUtils.formatDate(result.getString("Shipment Date"), "MMM dd yyyy", "MM/dd/yyyy");
                nextLocation = result.getString("Ship to");
                String shipmentNo = result.getString("Shipment #");
               
                if ( partNumber != null && partNumber.trim().length() > 0 && lotNumber != null && lotNumber.trim().length() > 0
                        && "package".equalsIgnoreCase(result.getString("Pkg Matl") ) )
                {
                    shippedLot = (ShippedLot) m_fabShipDataMap.get(partNumber + lotNumber + shipDate + shipmentNo + nextLocation + result.getString("Customer PO #") );
                    if (shippedLot == null)
                    {
                        shippedLot = new ShippedLot(VENDOR_NAME_IBM, LOCATION_TYPE_FAB );
                        m_fabShipDataMap.put(partNumber + lotNumber + shipDate + shipmentNo + nextLocation + result.getString("Customer PO #") , shippedLot);
                    }

                    int quantity = 0;
                    if ( shippedLot.getShipQty() != null )
                    {
                       try
                       {
                           quantity = Integer.parseInt( shippedLot.getShipQty() );
                       }
                       catch ( NumberFormatException ignore )
                       {
                           quantity = 0;
                       }
                       if ( result.getString("Wafer ID") != null )
                       {
                           quantity += 1;
                       }
                       else
                       {
                            quantity += result.getInt("Quantity");
                       }
                    }
                    else
                    {
                        if ( result.getString("Wafer ID") != null )
                        {
                            quantity = 1;
                        }
                        else
                        {
                            quantity = result.getInt("Quantity");
                        }
                    }
                    if ( quantity > 0 )
                    {
                        shippedLot.setLotNumber( lotNumber );
                        shippedLot.setPartNumber( partNumber );
                        shippedLot.setShipDate( shipDate );
                        shippedLot.setShipQty( quantity + "");
                        shippedLot.setCustomerPO( result.getString("Customer PO #") );
                        shippedLot.setShippingDoc( shipmentNo );
                        shippedLot.setInvoiceNumber( result.getString("Commercial Invoice") );
                        shippedLot.setNextLocation( nextLocation );
                        shippedLot.setFabLotNumber( lotNumber );
                        //Nov-19-2009 17:00:00 EST
                        /*if ( result.getString("Estimated time of Arrival") != null )
                        {
                            shippedLot.setEta(StringUtils.formatDate(result.getString("Estimated time of Arrival"), "MMM-dd-yyyy HH:mm:ss zzz", "MM/dd/yyy HH:mm:ss") );
                        }
                        if ( result.getString("Estimated time of Departure") != null )
                        {
                            shippedLot.setEtd( StringUtils.formatDate(result.getString("Estimated time of Departure"), "MMM-dd-yyyy HH:mm:ss zzz", "MM/dd/yyy HH:mm:ss") ) ;
                        } */
                        shippedLot.setProcessType( LOCATION_TYPE_FAB );

                    }
                }
            }
        }
        catch(Exception ex)
        {
            System.out.println("ERROR!!!ERROR!!! While Parsing the IBM Ship Report");
            ex.printStackTrace();
            throw ex;

        }
    }

     private static void log( String message )
     {
        if ( message == null ) return;

        if ( m_parserLogger != null )
        {
            synchronized ( m_parserLogger )
            {
                m_parserLogger.logDebug( message + LINE_SEPARATOR );
            }
        }
        else
        {
            System.out.println( message );
        }
    }
}
